{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "406c2750",
   "metadata": {},
   "source": [
    "# Bike Share Rebalancing With Mathematical Optimization"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7a7e7404",
   "metadata": {},
   "source": [
    "Bike share systems have become an effective commuting method globally for everyday urban dwellers as well as tourists.\n",
    "\n",
    "Citi-Bike in NYC being the largest Bike-Sharing network had 1,588 active stations and 25,575 active bikes in July 2022.\n",
    "\n",
    "Over 3 million rides were completed July 2022 that cover NYC/Hoboken/Jersey City, with around 150,000 active annual members.\n",
    "\n",
    "During rush hours there are many bike stations that have a high demand for bikes, which means their out-flow of bikes is greater than their in-flow in these stations. \n",
    "\n",
    "Meanwhile there are stations that have a high demand for docks (riders return their bikes to these stations) which means their in-flow of bikes is greater than their out-flow.\n",
    "\n",
    "Lack of available bikes or docks in high-demand stations can cause major imbalance in the bike sharing network and result in customer dissatisfaction and lost revenue.\n",
    "\n",
    "To tackle this problem, bikes are relocated between stations to create a balance between supply and demand."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3fdb0fdf",
   "metadata": {},
   "source": [
    "## Problem Statement and Solution Approach"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d2142854",
   "metadata": {},
   "source": [
    "Using historical Citi-bike data in NYC and Jersey area during July 2022, we like to know:\n",
    "- What is the demand for bikes per hour at each station during the first week of August?\n",
    "- Knowing the demand, how can we minimize loss of sale?\n",
    "\n",
    "Loss of sale is caused by lack of bikes when customers demand them. So, bikes should be transfered from stations with higher in-flow of bikes to those with higher out-flow of bikes. \n",
    "\n",
    "So, first, number of bikes to be added to or removed from each station during each hour should be determined. Then, the physical transfer of bikes between stations should be scheduled. \n",
    "\n",
    "In this notebook, we'll focus on the first part and at the end, discuss how the second part can be solved.\n",
    "We'll use a mixture of Machine Learning (ML) and Mathematical Optimization (MO) to solve this problem. \n",
    "\n",
    "**Solution Approach**\n",
    "The solution approach is comprised of two steps:\n",
    "- **Step 1**: We use the historical Citi-bike data in NYC and Jersey area during July 2022 and use an ML model to predict the number of in-flow and out-flow of bikes per hour at each station for the first week of August. This notebook accomplishes this step.\n",
    "- **Step 2**: We use an MO model to decide how many bikes should be added to or removed from each station during each hour so that the total loss of sale is minimized. This is done in [bike_rebalancing](bike_rebalancing.ipynb) Notebook.\n",
    "\n",
    "To ensure that everyone can run the notebook with the gurobi restricted license, we reduce the size of the data. To achieve that, we focus on the top 50 stations during the morning rush hours (7 am to 9 am).\n",
    "\n",
    "The top stations are chosen using the PageRank algorithm."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a8bd6f69",
   "metadata": {},
   "source": [
    "# Import Packages"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "4036b5a7",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-11-12T12:18:19.901609Z",
     "start_time": "2022-11-12T12:18:16.625440Z"
    }
   },
   "outputs": [],
   "source": [
    "import datetime\n",
    "import io\n",
    "import json\n",
    "import matplotlib.pyplot as plt\n",
    "import networkx as nx\n",
    "import pandas as pd\n",
    "import requests\n",
    "from sklearn.linear_model import LinearRegression\n",
    "from sklearn.metrics import r2_score\n",
    "from sklearn.svm import LinearSVR\n",
    "from xgboost import XGBRegressor\n",
    "from zipfile import ZipFile"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6cb80ad5",
   "metadata": {},
   "source": [
    "# Collect, Analyze, and Create Required Data"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9c2cf6bd",
   "metadata": {},
   "source": [
    "## Citi Bike Trip Histories\n",
    "\n",
    "To get Citi Bike trip data:\n",
    "- Go to [this](https://ride.citibikenyc.com/system-data) link\n",
    "- Click the link under Citi Bike Trip Histories\n",
    "- Download \"[202207-citbike-tripdata.csv.zip](https://s3.amazonaws.com/tripdata/202207-citbike-tripdata.csv.zip)\" and \"[JC-202207-citbike-tripdata.csv.zip](https://s3.amazonaws.com/tripdata/JC-202207-citbike-tripdata.csv.zip)\"\n",
    "\n",
    "\n",
    "[July Citi-Bike Monthly Report](https://mot-marketing-whitelabel-prod.s3.amazonaws.com/nyc/July-2022-Citi-Bike-Monthly-Report.pdf) Stats:\n",
    "\n",
    "- Average Bike Fleet: 25,575 Bikes\n",
    "- Active Stations: 1,588\n",
    "- Average Rides/Day: 109,305 - each bike used 4.13 times/day\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "2e7f1760",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-11-12T12:18:21.253047Z",
     "start_time": "2022-11-12T12:18:21.242057Z"
    }
   },
   "outputs": [],
   "source": [
    "def download_zip_to_dataframe(url):\n",
    "    response = requests.get(url)\n",
    "    with ZipFile(io.BytesIO(response.content)) as zf:\n",
    "        with zf.open(zf.namelist()[0]) as f:\n",
    "            df = pd.read_csv(f, low_memory=False)\n",
    "    return df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "cadc5750",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-11-12T12:18:56.741692Z",
     "start_time": "2022-11-12T12:18:22.306863Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "ride_id                  0\n",
       "rideable_type            0\n",
       "started_at               0\n",
       "ended_at                 0\n",
       "start_station_name       0\n",
       "start_station_id         0\n",
       "end_station_name      9756\n",
       "end_station_id        9756\n",
       "start_lat                0\n",
       "start_lng                0\n",
       "end_lat               4857\n",
       "end_lng               4857\n",
       "member_casual            0\n",
       "dtype: int64"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Read the data directly from the url\n",
    "# NYC data\n",
    "nyc_citi_jul_2022 = download_zip_to_dataframe('https://raw.githubusercontent.com/Gurobi/modeling-examples/master/optimization101/bike_share/202207-citbike-tripdata.csv.zip')\n",
    "# Jersey data\n",
    "jersey_citi_jul_2022 = download_zip_to_dataframe('https://raw.githubusercontent.com/Gurobi/modeling-examples/master/optimization101/bike_share/JC-202207-citbike-tripdata.csv.zip')\n",
    "citi_jul_network = pd.concat([nyc_citi_jul_2022, jersey_citi_jul_2022])\n",
    "pd.isnull(citi_jul_network).sum()  # count of null values in each column"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "ec0bebcf",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-11-12T12:19:04.738859Z",
     "start_time": "2022-11-12T12:18:56.789998Z"
    }
   },
   "outputs": [],
   "source": [
    "# There is a small number of missing end stations. drop them\n",
    "citi_jul_network.dropna(inplace=True)\n",
    "# Found a naming discrepancy 'Broadway\\t& W 48 St' and 'Broadway\\\\t& W 48 St'.\n",
    "# replacing with 'Broadway & W 48 St' so they all match\n",
    "citi_jul_network['start_station_name'] = citi_jul_network['start_station_name'].replace(\n",
    "    ['Broadway\\t& W 48 St'], 'Broadway & W 48 St')\n",
    "citi_jul_network['start_station_name'] = citi_jul_network['start_station_name'].replace(\n",
    "    ['Broadway\\\\t& W 48 St'], 'Broadway & W 48 St')\n",
    "citi_jul_network['end_station_name'] = citi_jul_network['end_station_name'].replace(\n",
    "    ['Broadway\\t& W 48 St'], 'Broadway & W 48 St')\n",
    "citi_jul_network['end_station_name'] = citi_jul_network['end_station_name'].replace(\n",
    "    ['Broadway\\\\t& W 48 St'], 'Broadway & W 48 St')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3670270d",
   "metadata": {},
   "source": [
    "## Station Information\n",
    "Citi Bike publishes real-time system data which can be retrieved from [this](http://gbfs.citibikenyc.com/gbfs/gbfs.json) link."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "d1f8e80e",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-11-12T12:19:04.786173Z",
     "start_time": "2022-11-12T12:19:04.771167Z"
    }
   },
   "outputs": [],
   "source": [
    "def get_stations_info():\n",
    "    response_api = requests.get('https://gbfs.citibikenyc.com/gbfs/es/station_information.json')\n",
    "    parse_json = json.loads(response_api.text)\n",
    "    stations = parse_json['data']['stations']\n",
    "    stations_dict = {}\n",
    "    for station in stations:\n",
    "        if 'region_id' in station:\n",
    "            stations_dict[station['name']] = {'capacity': station['capacity'],\n",
    "                                              'lat': station['lat'],\n",
    "                                              'lon': station['lon'],\n",
    "                                              'region': station['region_id']}\n",
    "    if 'Broadway\\t& W 48 St' in stations_dict:\n",
    "        stations_dict['Broadway & W 48 St'] = stations_dict.pop('Broadway\\t& W 48 St')  # replace to match other names\n",
    "    stations_info = pd.DataFrame(stations_dict).T\n",
    "    # Drop stations with capacity = 0\n",
    "    stations_info = stations_info.loc[stations_info.capacity > 0]\n",
    "    return stations_info"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "12cff6ed",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-11-12T12:19:05.414661Z",
     "start_time": "2022-11-12T12:19:04.821035Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>capacity</th>\n",
       "      <th>lat</th>\n",
       "      <th>lon</th>\n",
       "      <th>region</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>W 52 St &amp; 11 Ave</th>\n",
       "      <td>17</td>\n",
       "      <td>40.767272</td>\n",
       "      <td>-73.993929</td>\n",
       "      <td>71</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Franklin St &amp; W Broadway</th>\n",
       "      <td>33</td>\n",
       "      <td>40.719116</td>\n",
       "      <td>-74.006667</td>\n",
       "      <td>71</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>St James Pl &amp; Pearl St</th>\n",
       "      <td>27</td>\n",
       "      <td>40.711174</td>\n",
       "      <td>-74.000165</td>\n",
       "      <td>71</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Atlantic Ave &amp; Fort Greene Pl</th>\n",
       "      <td>62</td>\n",
       "      <td>40.683826</td>\n",
       "      <td>-73.976323</td>\n",
       "      <td>71</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>W 17 St &amp; 8 Ave</th>\n",
       "      <td>74</td>\n",
       "      <td>40.741776</td>\n",
       "      <td>-74.001497</td>\n",
       "      <td>71</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                              capacity        lat        lon region\n",
       "W 52 St & 11 Ave                    17  40.767272 -73.993929     71\n",
       "Franklin St & W Broadway            33  40.719116 -74.006667     71\n",
       "St James Pl & Pearl St              27  40.711174 -74.000165     71\n",
       "Atlantic Ave & Fort Greene Pl       62  40.683826 -73.976323     71\n",
       "W 17 St & 8 Ave                     74  40.741776 -74.001497     71"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "stations_info = get_stations_info()\n",
    "stations_info.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dc5cd448",
   "metadata": {},
   "source": [
    "## Get Top Stations\n",
    "PageRank is used to get the top stations"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "01fe3c7a",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-11-12T12:19:09.087524Z",
     "start_time": "2022-11-12T12:19:05.446537Z"
    }
   },
   "outputs": [],
   "source": [
    "citi_df = citi_jul_network.groupby(['start_station_name', 'end_station_name'], \n",
    "                                   sort=False)['ride_id'].count().reset_index()\n",
    "g = nx.from_pandas_edgelist(citi_df, source='start_station_name', target='end_station_name',\n",
    "                            edge_attr='ride_id', create_using=nx.DiGraph)\n",
    "wpr_scores_fwd = pd.Series(nx.pagerank(g, weight='ride_id')).sort_values(ascending=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "325aa38b",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-11-12T12:19:09.555679Z",
     "start_time": "2022-11-12T12:19:09.135803Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Text(0, 0.5, 'PageRank Value')"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjwAAAJmCAYAAABYGloLAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy89olMNAAAACXBIWXMAAAxOAAAMTgF/d4wjAACv5klEQVR4nOzdd1gU5/c28HuxKyKoGFQEBcQKAvaKWImx994VTdQkGks0xlijiRpbjBoLtmCP7WsvROwVJRobFrBgiYAiIu28f/AyP1bREGZGYHN/rmsvmbJnnh13ds8+8xSDiAiIiIiITJhZRheAiIiISG9MeIiIiMjkMeEhIiIik8eEh4iIiEweEx4iIiIyeUx4iIiIyOQx4SEiIiKTx4SHiMjEffzxx5g8eXJGF4MoQzHhIcqEzM3NlUfOnDmRLVs2o3UBAQGaHm/MmDFwcXGBhYUFihYtii5duiA0NNRon5CQEDRv3hz58+dH4cKFMWTIEMTGxr4zpq+vL2xtbTUtp5YMBgMOHDigedySJUti6dKl/7jfkiVL4OrqigIFCsDS0hKurq6YP3++sr1+/fr45ptv/tWx79y5A4PBgJs3bxqt3717N8aPH/+vYhGZGiY8RJlQVFSU8hg1ahTq1q1rtK5u3bqaHs9gMMDX1xdPnz7FX3/9BYPBgBYtWijbExMT0bx5cxQsWBD379/HuXPncOTIEYwcOVLTcnwI70vSPpT169dj7Nix+PnnnxEeHo5Hjx5h2bJlKF68eEYXjch0CRFlauPGjRNPT09lOTw8XAYMGCDFixeXQoUKibe3t1y9elXZPmHCBKldu7aMGTNGrK2t5aOPPpKvvvpKYmNj03zMCxcuCAB59uyZiIj4+/tL9uzZ5cmTJ8o+W7dulbx588qrV69SjbFixQopXrz4W+UaP3682NjYSP78+WXkyJHy7Nkz6dixo1hYWIi9vb1s3br1rRhz5syR4sWLS8GCBaVPnz7y4sULZZ979+5Jhw4dpEiRIlKkSBHp2LGj3L9/X9neq1cv6dChgwwaNEgKFy4s3t7eUr58eQEguXPnlnz58om3t7eIiGzYsEE8PDzE0tJSChUqJC1atJBbt269VZ5FixaJvb29WFhYSPv27SUyMlJERLy9vcVgMEiuXLkkX758Ur58+VTPzZAhQ6RFixbvPP8+Pj5iZmYmOXLkkHz58km+fPlERCQoKEgaNGgghQsXFgsLC6lWrZocPHhQeV7evHkFgOTNm1fy5csnPj4+IiLi6ekp48aNU/a7cuWKeHt7S6FChaR48eIycOBAiYiIULZ7enrKsGHDpEuXLmJhYSG2traycOFCZfvdu3fl448/FisrK7GwsJAKFSrIkSNH3vl6iDID1vAQZTE9evTAjRs3cPbsWYSEhKBMmTJo1KgRoqKilH1OnTqF7NmzIzQ0FP7+/ti8eTN++OGHNB9j3759sLe3h5WVFQAgMDAQDg4OKFy4sLJP1apVER0djevXr6c57qlTp1CoUCGEhITg4MGD+Omnn9C4cWMMGTIE4eHhGDZsGPr06YPo6GjlOWFhYQgMDMS1a9dw6dIlBAUF4csvvwQAJCQkoHnz5siWLRuuX7+Oa9euQUTQsmVLJCQkKDF+//13VK1aFQ8ePMDmzZtx+fJlAMCOHTsQFRWF3bt3AwDy58+P5cuX4+nTp7h69SpEBF27djV6DWFhYbh69Sr++usvXL16FYGBgZg1axaApFtHdnZ2WLBgAaKiopTjvKl+/frYs2cPRo8ejX379uHp06dG2xctWoS6deti1KhRSq1esjFjxiAkJASPHz/Gxx9/jDZt2uDx48cAoBzv4sWLiIqKwqJFi9469osXL9CoUSOUL18eISEhOHPmDK5evYpevXoZ7efr64v+/fsjPDwcc+bMwZAhQ5RbZV9//TWKFy+OBw8eIDw8HJs3b87Uty+JALCGhyizS1nD8+DBAwEggYGByvbY2FgpVKiQ+Pn5iUhSTUqRIkUkPj5e2WfhwoXi4OCQpuPt379f8ubNK7t371bWTZo0SapVq2a0X3R0tACQgICAVOOkVsPzZhnc3Nxk4MCByvLTp0+NXt+KFSvEzMzMqPZh165dkiNHDomPj5fjx4+LwWBQaqKSYxgMBjlx4oSIJNXw1KhR463yAZD9+/e/91ycP39eAMjz58+V8uTKlcuotuyrr75SaohEROzt7eXXX399b1wRkd27d0uHDh2kWLFiYjAYpFq1anLs2DFl+5u1Mu9SoEAB2b59u4iI3L59WwDIjRs3jPZJGeu3336TwoULS1xc3Fuv8+HDh8r+ffr0MYpRuHBhWbdunYiI9O7dW5o3by5//vmnJCYm/mMZiTID1vAQZSHJDYkdHR2VdTly5IC9vT1CQkKUdSVKlEC2bNmU5VKlSr3VCDk1O3fuRPv27bFmzRp4e3sr6y0sLBAREWG0b3h4uLItrYoWLWq0nC9fPqN1+fLlA5BUC5HMysoKBQoUMHotcXFxePToEUJDQ1GwYEGlJgoAChUqBCsrK6PzUapUqTSV748//kDDhg1RtGhRWFhYwNPTEwCUGhQAKFy4MHLkyGFU5pTlTStvb29s2LAB9+/fx+3bt1GyZEk0a9YMkZGR73xOSEgIOnfuDDs7O1hYWMDS0hLPnz83Kt8/CQ0Nhb29PbJnz66sc3JyUuInK1asmNHzUr7OmTNnwsnJCW3btsVHH32EPn364NGjR2kuA1FGYMJDlIWUKFECABAcHKysi4+PR0hICOzs7JR1oaGhRrd07ty584+3HNauXYtu3bph/fr1aNOmjdE2Nzc33L59G3///bey7uzZs8ibNy+cnZ1VvaZ/Eh4ebpQE3LlzBzly5MBHH32EEiVKIDw8XEm+AODZs2cIDw83Oh9mZm9/1BkMBqPl2NhYNG/eHN7e3rh+/TqeP3+OP/74AwAgImkub2rH+if29vb45ptvEBkZqfzfphZnwIABSExMxJkzZ/D8+XOEh4fDwsJCKV9ajl2iRAmEhIQgPj5eWZd8zJTn7H0KFSqEn376CdeuXcOFCxdw584dDB8+PE3PJcooTHiIspCiRYuiWbNmGDFiBB49eoRXr15h9OjRyJkzJz755BNlv2fPnmHSpEl4/fo1rl27hh9//BF9+vR5Z9wFCxZgyJAh2LlzJ5o2bfrW9rp166Js2bIYMWIEXrx4gZCQEHz77bfo168fcufOrctrTWYwGDBixAi8fPkSDx48wIQJE9CjRw9ky5YN1apVQ8WKFTFkyBA8f/4ckZGR+Oyzz+Dm5oaqVau+N66NjQ2uXbumLMfGxuLVq1ewsrJC/vz58eDBg3/dLTy1uKlZvnw51q9fr9TMPHnyBLNnz4a1tTXKlSunxHmzfVRkZCTMzc1hZWWFly9f4uuvvzZq32NtbQ0zM7P3Hv+TTz5B9uzZMXbsWLx69QphYWH48ssv0aJFC9jY2KTpNa5btw7BwcFITExE/vz5kStXLqMaI6LMiAkPURazevVqlCxZEh4eHrC1tcXly5dx4MAB5M+fX9mnevXqiI2Nha2tLerVq4fWrVtjzJgx74w5dOhQREVF4eOPP051vB8zMzPs2LEDT548QdGiReHu7o46dergxx9/1P312tjYwMXFBc7OzqhYsSLKlSuHOXPmAACyZcuGnTt34vXr13ByckLp0qURHx+P7du3G93SS83333+PGTNmwNLSEs2bN4e5uTmWLl2KKVOmwNzcHB9//DE6dOjwr8v77bffYtu2bcrYOqkpWLAglixZgooVKyJfvnxwdXVFREQEDhw4gDx58gAARowYgWvXrsHKygqWlpYAgHnz5uHixYuwsrJC+fLlUbx4caOauzx58mDatGno378/LC0t8emnn751bAsLC+zfvx8XL16Era0tKleuDCcnJ6xcuTLNr/HixYto0KAB8ufPD0dHR1haWmLmzJn/4iwRfXgG+Td1tUSU6X333Xc4cOAAjh49mtFFUc3X1xfffPMN7t27l9FFIaIsjjU8REREZPKY8BAREZHJ4y0tIiIiMnms4SEiIiKTx4SHiIiITB4HTkhFrly5YG1tndHFICIion/hyZMneP36darbmPCkwtramt1giYiIspj3jSjPW1pERERk8pjwEBERkcljwkNEREQmjwkPERERmTwmPERERGTymPAQERGRyWPCQ0RERCaPCQ8RERGZPCY8REREZPKY8BAREZHJY8JDREREJo8JDxEREZk8JjxERERk8pjwEBERkcljwkNEREQmjwkPERERmbzsGV2A/5qSY/6nSZw70z/RJA4REdF/AWt4iIiIyOQx4SEiIiKTx4SHiIiITB4THiIiIjJ5THiIiIjI5DHhISIiIpPHhIeIiIhMHhMeIiIiMnlMeIiIiMjkMeEhIiIik8eEh4iIiEweEx4iIiIyeUx4iIiIyOQx4SEiIiKTx4SHiIiITB4THiIiIjJ5THiIiIjI5DHhISIiIpPHhIeIiIhMHhMeIiIiMnlMeIiIiMjk6Z7w3LhxA7Vq1YKzszOqVq2Ky5cvp7rfsmXLULp0aTg6OmLAgAGIi4v7x22HDh1CtWrVUL58eVSoUAGjRo1CYmIiAODOnTvIli0b3NzclEdwcLDeL5eIiIgyId0THh8fHwwcOBDXr1/H6NGj0bt377f2uX37NsaPH4+AgADcvHkTjx49wpIlS/5xm5WVFdatW4crV67g3LlzOH78OFatWqXEzZ8/PwIDA5WHo6Oj3i+XiIiIMiFdE57Hjx/j7Nmz6N69OwCgXbt2CA0Nxc2bN43227RpE1q2bAkb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ZSMiIiLSxHsTnjZt2sBgMPzfztmzI2fOnOjRowcAYMuWLfqWjoiIiEgD7014WrdubbTcqlUrPctCREREpIv3Jjy9evX6UOUgIiIi0k2a2vBERERg8eLFCA4OVsbUAYDly5frVjAiIiIiraQp4Wnfvj2sra1Rs2bNdM2pRURERJSR0pTwPHz4EAcOHNC7LERERES6SNPAg46OjoiIiNC5KERERET6SFMNT968eeHh4QFvb2+j8XdSTrhJRERElFmlKeEpV64cypUrp3dZiIiIiHSRpoRnwoQJepeDiIiISDdpSngA4PTp0wgMDERMTIyybtiwYboUioiIiEhLaUp4pk2bhk2bNiEkJASenp7Yv38/GjZsyISHiIiIsoQ09dL67bffcPz4cdja2mLz5s04c+YMzMzS9FQiIiKiDJemrCV37tzInTs3EhMTISIoU6YMgoOD9S4bERERkSbSdEsrT548iIuLg5ubG7766ivY2toiISFB77IRERERaSJNNTy//PILYmNjMWvWLDx//hzHjh3DmjVr9C4bERERkSbSVMNTsWJFAEC+fPnw66+/AgB+//13VKpUSb+SEREREWnkH2t4Nm3ahFmzZuHatWsAgL1796Jy5cr4+uuvdS8cERERkRbem/AMHz4co0ePxpkzZ9CmTRuMGDECnTp1Qu/evfHnn39+qDISERERqfLeW1q7d+9GYGAg8ufPj4cPH6JkyZI4e/YsXFxcPlT5iIiIiFR7bw1Pnjx5kD9/fgBA0aJF4ezszGSHiIiIspz31vBERERg+/btynJ0dLTRcsuWLfUrGREREZFG3pvw2NnZ4aeffkp12WAwMOEhIiKiLOG9CY+/v/8HKgYRERGRftI8IdbmzZsxbdo0AMCDBw8QFBSkW6GIiIiItJSmhOfbb7/F0qVL4evrCyDpdpaPj4+e5SIiIiLSTJoSnm3btmHnzp3Ily8fgKQeW1FRUboWjIiIiEgraUp48uTJg2zZshmtExFdCkRERESktTTNpWVvb4+AgAAYDAbExcVh2rRpcHNz07loRERERNpIU8Izb9489OrVC0FBQciXLx+8vLywdu1avctGREREpIk0JTwfffQR9uzZg+joaIiI0paHiIiIKCtIU8Jz5MiRt9ZZWlrC2dkZuXPn1rxQRERERFpKU8IzbNgwBAUFwcHBAQaDAcHBwShTpgwi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",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(8, 6), dpi=80)\n",
    "plt.xticks(rotation=90)\n",
    "plt.bar(wpr_scores_fwd.index[:20], wpr_scores_fwd.values[:20])\n",
    "plt.title('Top 20 Important Stations')\n",
    "plt.xlabel('Stations')\n",
    "plt.ylabel('PageRank Value')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a141a0a1",
   "metadata": {},
   "source": [
    "## Combining and Filtering Data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "8fa57158",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-11-12T12:19:09.618487Z",
     "start_time": "2022-11-12T12:19:09.607019Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(45, 4)"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Grab the top N stations according to importance in the network\n",
    "n = 50  # User can define how many stations to select\n",
    "top_stations = list(wpr_scores_fwd.head(n).index)\n",
    "# Filter stations info for only the top N stations\n",
    "top_stations_info = stations_info[stations_info.index.isin(top_stations)]\n",
    "top_stations_info.shape  # Some stations are not in stations_info"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "e0709871",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-11-12T12:19:09.681859Z",
     "start_time": "2022-11-12T12:19:09.667226Z"
    }
   },
   "outputs": [],
   "source": [
    "# There is discrepancy between stations that are retrived from the live station data and \n",
    "# those in citi_jul_network.\n",
    "# So, the station values in `top_station_info` is used as the base\n",
    "top_stations = top_stations_info.index"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "bab9a050",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-11-12T12:19:25.711002Z",
     "start_time": "2022-11-12T12:19:24.018886Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\Ehsan\\AppData\\Local\\Temp\\ipykernel_7012\\2574193657.py:3: SettingWithCopyWarning: \n",
      "A value is trying to be set on a copy of a slice from a DataFrame.\n",
      "Try using .loc[row_indexer,col_indexer] = value instead\n",
      "\n",
      "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
      "  citi_jul_network_top['started_at'] = pd.to_datetime(citi_jul_network_top['started_at']).dt.round('h')\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "start_station_name  started_at         \n",
       "1 Ave & E 62 St     2022-07-01 00:00:00    1\n",
       "                    2022-07-01 01:00:00    4\n",
       "                    2022-07-01 02:00:00    2\n",
       "                    2022-07-01 04:00:00    2\n",
       "                    2022-07-01 06:00:00    5\n",
       "Name: start, dtype: int64"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Start\n",
    "citi_jul_network_top = citi_jul_network[citi_jul_network['start_station_name'].isin(top_stations)]\n",
    "citi_jul_network_top['started_at'] = pd.to_datetime(citi_jul_network_top['started_at']).dt.round('h')\n",
    "citi_jul_2022_start = citi_jul_network_top.groupby(['start_station_name', 'started_at']).size().rename('start')\n",
    "citi_jul_2022_start.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "56b6cb5d",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-11-12T12:19:26.532376Z",
     "start_time": "2022-11-12T12:19:25.774624Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\Ehsan\\AppData\\Local\\Temp\\ipykernel_7012\\420661752.py:3: SettingWithCopyWarning: \n",
      "A value is trying to be set on a copy of a slice from a DataFrame.\n",
      "Try using .loc[row_indexer,col_indexer] = value instead\n",
      "\n",
      "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
      "  citi_jul_network_top['ended_at'] = pd.to_datetime(citi_jul_network_top['ended_at']).dt.round('h')\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "end_station_name  ended_at           \n",
       "1 Ave & E 62 St   2022-07-01 01:00:00    4\n",
       "                  2022-07-01 02:00:00    1\n",
       "                  2022-07-01 03:00:00    1\n",
       "                  2022-07-01 04:00:00    1\n",
       "                  2022-07-01 05:00:00    1\n",
       "Name: end, dtype: int64"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# End\n",
    "citi_jul_network_top = citi_jul_network[citi_jul_network['end_station_name'].isin(top_stations)]\n",
    "citi_jul_network_top['ended_at'] = pd.to_datetime(citi_jul_network_top['ended_at']).dt.round('h')\n",
    "citi_jul_2022_end = citi_jul_network_top.groupby(['end_station_name', 'ended_at']).size().rename('end')\n",
    "citi_jul_2022_end.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "e382506e",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-11-12T12:19:29.555636Z",
     "start_time": "2022-11-12T12:19:29.320768Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>station</th>\n",
       "      <th>datetime</th>\n",
       "      <th>start</th>\n",
       "      <th>end</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1 Ave &amp; E 62 St</td>\n",
       "      <td>2022-07-01 00:00:00</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1 Ave &amp; E 62 St</td>\n",
       "      <td>2022-07-01 01:00:00</td>\n",
       "      <td>4.0</td>\n",
       "      <td>4.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1 Ave &amp; E 62 St</td>\n",
       "      <td>2022-07-01 02:00:00</td>\n",
       "      <td>2.0</td>\n",
       "      <td>1.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>1 Ave &amp; E 62 St</td>\n",
       "      <td>2022-07-01 04:00:00</td>\n",
       "      <td>2.0</td>\n",
       "      <td>1.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1 Ave &amp; E 62 St</td>\n",
       "      <td>2022-07-01 06:00:00</td>\n",
       "      <td>5.0</td>\n",
       "      <td>2.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "           station            datetime  start  end\n",
       "0  1 Ave & E 62 St 2022-07-01 00:00:00    1.0  0.0\n",
       "1  1 Ave & E 62 St 2022-07-01 01:00:00    4.0  4.0\n",
       "2  1 Ave & E 62 St 2022-07-01 02:00:00    2.0  1.0\n",
       "3  1 Ave & E 62 St 2022-07-01 04:00:00    2.0  1.0\n",
       "4  1 Ave & E 62 St 2022-07-01 06:00:00    5.0  2.0"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Combining the hourly ride starts and end for each station\n",
    "citi_jul_2022_hourly_combined = pd.concat(\n",
    "    [citi_jul_2022_start, citi_jul_2022_end], axis=1).fillna(0).reset_index().rename(\n",
    "    columns={'level_0': 'station', 'level_1': 'datetime'})\n",
    "citi_jul_2022_hourly_combined.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "633c5112",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-11-12T12:19:31.119344Z",
     "start_time": "2022-11-12T12:19:30.951917Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>station</th>\n",
       "      <th>datetime</th>\n",
       "      <th>start</th>\n",
       "      <th>end</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1 Ave &amp; E 62 St</td>\n",
       "      <td>2022-07-01 00:00:00</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1 Ave &amp; E 62 St</td>\n",
       "      <td>2022-07-01 01:00:00</td>\n",
       "      <td>4.0</td>\n",
       "      <td>4.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1 Ave &amp; E 62 St</td>\n",
       "      <td>2022-07-01 02:00:00</td>\n",
       "      <td>2.0</td>\n",
       "      <td>1.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>1 Ave &amp; E 62 St</td>\n",
       "      <td>2022-07-01 04:00:00</td>\n",
       "      <td>2.0</td>\n",
       "      <td>1.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1 Ave &amp; E 62 St</td>\n",
       "      <td>2022-07-01 06:00:00</td>\n",
       "      <td>5.0</td>\n",
       "      <td>2.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "           station            datetime  start  end\n",
       "0  1 Ave & E 62 St 2022-07-01 00:00:00    1.0  0.0\n",
       "1  1 Ave & E 62 St 2022-07-01 01:00:00    4.0  4.0\n",
       "2  1 Ave & E 62 St 2022-07-01 02:00:00    2.0  1.0\n",
       "3  1 Ave & E 62 St 2022-07-01 04:00:00    2.0  1.0\n",
       "4  1 Ave & E 62 St 2022-07-01 06:00:00    5.0  2.0"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Cleaning and saving data as full time series\n",
    "data = citi_jul_2022_hourly_combined\n",
    "data = data[data['datetime'].isin(pd.date_range(start='7/1/2022', end='7/31/2022 23:00:00', freq='H'))]\n",
    "new_index = pd.MultiIndex.from_product([data.station.unique(), data.datetime.unique()])\n",
    "clean_full_time_series = data.set_index(\n",
    "    ['station', 'datetime']).reindex(new_index).fillna(0).reset_index().rename(\n",
    "    columns={'level_0': 'station', 'level_1': 'datetime'})\n",
    "clean_full_time_series.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f9ba5fcb",
   "metadata": {},
   "source": [
    "# Citi-Bike July 2022 ML Modeling"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2e5df46a",
   "metadata": {},
   "source": [
    "## Create Master ML Dataframe\n",
    "This needs to be done for both trips' start and end "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "9f3daad7",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-11-12T12:19:40.577042Z",
     "start_time": "2022-11-12T12:19:40.568892Z"
    }
   },
   "outputs": [],
   "source": [
    "def prep_ml_df(col):\n",
    "    \"\"\"\n",
    "    Flattens out data. Instead of timeseries running down the rows, it runs across the columns.\n",
    "    Grabbing preceding 12 hours for last week, 2 week ago.\n",
    "\n",
    "    Forecasting one week into the future. Hourly -> 168 hours\n",
    "    \"\"\"\n",
    "    mdf = clean_full_time_series[['station', 'datetime', col]].sort_values('datetime')\n",
    "    ml_master_ls = []\n",
    "    hours_prediction_horizon = 168  # hours in a week\n",
    "    num_lagging_windows = hours_prediction_horizon + 12  # 12 hours leading up to time x\n",
    "    # go through each chunk of data by ts_id\n",
    "    for grp, df in mdf.groupby('station'):\n",
    "        # add lagging demand data\n",
    "        for n in range(hours_prediction_horizon, num_lagging_windows + 1):\n",
    "            df[f'{col}_lag_{n}'] = df[col].shift(n)  # one week past\n",
    "            df[f'{col}_lag_{n + 168}'] = df[col].shift(n + 168)  # two\n",
    "        ml_master_ls.append(df)\n",
    "    # bring it all back together\n",
    "    ml_master_df = pd.concat(ml_master_ls, axis=0, ignore_index=True).dropna(axis=0)\n",
    "    return ml_master_df, mdf"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "d5e4b675",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-11-12T12:19:42.302660Z",
     "start_time": "2022-11-12T12:19:41.536434Z"
    }
   },
   "outputs": [],
   "source": [
    "# Creating ML dataframe for 'start'\n",
    "ml_master_df_start, master_df_start = prep_ml_df('start')\n",
    "# Creating ML dataframe for 'end'\n",
    "ml_master_df_end, master_df_end = prep_ml_df('end')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6f97159e",
   "metadata": {},
   "source": [
    "## Split Training and Test"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6b7b024d",
   "metadata": {},
   "source": [
    "### Define train-test split"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "bb6868bd",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-11-12T12:19:45.398443Z",
     "start_time": "2022-11-12T12:19:45.392442Z"
    }
   },
   "outputs": [],
   "source": [
    "def train_test_data(ml_df, start_end, train_test_cutoff):\n",
    "    \"\"\"Separate the ml_df into training and test sets\n",
    "    \n",
    "    we preserve the training and testing data keys to keep track of our predictions later    \n",
    "    we create the data after the clustering code below    \n",
    "    Note: we should add logic to make sure we dropped start from X_... datasets\n",
    "    \"\"\"\n",
    "    # get model feature data\n",
    "    train_mask = ml_df.datetime < train_test_cutoff\n",
    "    X_train = ml_df[train_mask].copy()\n",
    "    X_test = ml_df[~train_mask].copy()\n",
    "\n",
    "    # get the model targets\n",
    "    y_train = X_train[start_end]\n",
    "    y_test = X_test[start_end]\n",
    "\n",
    "    # drop the unused columns\n",
    "    extra_cols = ['station', 'datetime', start_end]\n",
    "    X_train.drop(extra_cols, axis=1, inplace=True)\n",
    "    X_test.drop(extra_cols, axis=1, inplace=True)\n",
    "    return X_train, y_train, X_test, y_test"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "f2f69a42",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-11-12T12:19:46.635639Z",
     "start_time": "2022-11-12T12:19:46.601129Z"
    }
   },
   "outputs": [],
   "source": [
    "cutoff_time = datetime.datetime(year=2022, month=7, day=27)\n",
    "# Start\n",
    "X_train_start, y_train_start, X_test_start, y_test_start = train_test_data(ml_master_df_start, 'start', cutoff_time)\n",
    "# End\n",
    "X_train_end, y_train_end, X_test_end, y_test_end = train_test_data(ml_master_df_end, 'end', cutoff_time)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4bf32a24",
   "metadata": {},
   "source": [
    "## Running ML models and Testing"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "c0b8d297",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-11-12T12:19:48.348264Z",
     "start_time": "2022-11-12T12:19:48.337141Z"
    }
   },
   "outputs": [],
   "source": [
    "def create_ml_models(x_train, y_train, x_test, y_test):\n",
    "    best_model = None\n",
    "    best_model_name = None\n",
    "    best_score = 0\n",
    "    for name, regression in zip(['xgb', 'svm', 'linear regression'],\n",
    "                                [XGBRegressor, LinearSVR, LinearRegression]):\n",
    "        ml_model = regression()\n",
    "        ml_model.fit(x_train, y_train)\n",
    "        print(f'{name} results\\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~')\n",
    "        score = r2_score(y_test, ml_model.predict(x_test))\n",
    "        print(score)\n",
    "        if score > best_score:\n",
    "            best_score = score\n",
    "            best_model = ml_model\n",
    "            best_model_name = name\n",
    "    print(f'\\nBest model: {best_model_name}\\n')\n",
    "    return best_model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "1042ef60",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-11-12T12:19:57.532976Z",
     "start_time": "2022-11-12T12:19:53.500568Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "xgb results\n",
      "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n",
      "0.6930093092386995\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\Ehsan\\miniconda3\\envs\\bike\\lib\\site-packages\\sklearn\\svm\\_base.py:1225: ConvergenceWarning: Liblinear failed to converge, increase the number of iterations.\n",
      "  warnings.warn(\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "svm results\n",
      "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n",
      "0.5952978230973742\n",
      "linear regression results\n",
      "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n",
      "0.7352258784069108\n",
      "\n",
      "Best model: linear regression\n",
      "\n",
      "xgb results\n",
      "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n",
      "0.7006771976227817\n",
      "svm results\n",
      "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n",
      "0.7042649152534888\n",
      "linear regression results\n",
      "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n",
      "0.7278775214037927\n",
      "\n",
      "Best model: linear regression\n",
      "\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\Ehsan\\miniconda3\\envs\\bike\\lib\\site-packages\\sklearn\\svm\\_base.py:1225: ConvergenceWarning: Liblinear failed to converge, increase the number of iterations.\n",
      "  warnings.warn(\n"
     ]
    }
   ],
   "source": [
    "# Start\n",
    "ml_model_start = create_ml_models(X_train_start, y_train_start, X_test_start, y_test_start)\n",
    "# End\n",
    "ml_model_end = create_ml_models(X_train_end, y_train_end, X_test_end, y_test_end)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "303327d4",
   "metadata": {},
   "source": [
    "## Making Predictions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "56cd5866",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-11-12T12:19:57.814009Z",
     "start_time": "2022-11-12T12:19:57.795560Z"
    }
   },
   "outputs": [],
   "source": [
    "def create_prediction_df(master_df, ml_model, col):\n",
    "    ml_master_ls = []\n",
    "    hours_prediction_horizon = 168  # hours in a week\n",
    "    num_lagging_windows = hours_prediction_horizon + 12  # 12 hours leading up to time x\n",
    "    # go through each chunk of data by ts_id\n",
    "    date_range = pd.date_range(start='8/1/2022', end='8/5/2022 23:00:00', freq='H')\n",
    "    for grp, df in master_df.groupby('station'):\n",
    "        prediction_df = pd.DataFrame({'station': grp, col: 0, 'datetime': date_range})\n",
    "        df = pd.concat([df, prediction_df], axis=0, ignore_index=True)\n",
    "        # assure sorted\n",
    "        df.sort_values('datetime', inplace=True)\n",
    "        # add lagging demand data\n",
    "        for n in range(hours_prediction_horizon, num_lagging_windows + 1):\n",
    "            df[f'{col}_lag_{n}'] = df[col].shift(n)  # one week past\n",
    "            df[f'{col}_lag_{n + 168}'] = df[col].shift(n + 168)  # two\n",
    "        ml_master_ls.append(df)\n",
    "    # bring it all back together\n",
    "    ml_master_df = pd.concat(ml_master_ls, axis=0, ignore_index=True)\n",
    "    prediction_master = ml_master_df[ml_master_df['datetime'].isin(date_range)]\n",
    "    prediction_ml = prediction_master.drop(['station', 'datetime', col], axis=1)  # dataframe for model\n",
    "    # dataframe prediction key as placeholder for forecasts\n",
    "    prediction_key = prediction_master[['station', 'datetime']].copy()\n",
    "    prediction_key[f'{col}_forecast'] = ml_model.predict(prediction_ml)\n",
    "    return prediction_key"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "36136b5c",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-11-12T12:22:35.956500Z",
     "start_time": "2022-11-12T12:22:35.044628Z"
    }
   },
   "outputs": [],
   "source": [
    "# First week of August, MON-FRI predictions\n",
    "# Creating Prediction dataframe for 'start'\n",
    "start_prediction_key = create_prediction_df(master_df_start, ml_model_start, 'start')\n",
    "# Creating Prediction dataframe for 'end'\n",
    "end_prediction_key = create_prediction_df(master_df_end, ml_model_end, 'end')\n",
    "predictions_final = pd.merge(start_prediction_key, end_prediction_key, on=['station', 'datetime'])\n",
    "top_stations_info.to_csv('top_stations.csv', index_label='station')\n",
    "predictions_final.round(0).to_csv('stations_flow.csv', index=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "84c765bd",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.7"
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
